import { cesiumState, useSimulationStore } from "@/pinia/stores/index";
import {
  Cartesian3,
  Color,
  Entity,
  JulianDate,
  TimeInterval,
  TimeIntervalCollection,
  Math as CesiumMath,
  PolylineDashMaterialProperty,
  SampledPositionProperty,
  defined,
  DataSource,
  CallbackProperty,
  CustomDataSource,
} from "cesium";
import CustomViewer from "./CustomCesium/Core/CustomViewer";
import {
  ISideStep,
  IStepEntityInfo,
  ITrackEntityInfo,
  IEntityType,
} from "@@/typings/observation";
import moment from "moment";
import { SideEnum } from "@@/enums/observation";

interface IEntities {
  [propName: string | number]: RouteEntity;
}

/**
 * 实体轨迹
 */
interface RouteEntity {
  id: number | string;
  name: string;
  type?: IEntityType;
  side?: SideEnum | string;
  routes: number[];
  positions: { time: JulianDate[]; data: Cartesian3[] };
}

/**
 * 绘制轨迹
 */
export default class RoutesManager {
  // 实体 id: 位置数组[]
  entityRoutes: { [propName: string]: number[] };
  // DataSource
  datasource: DataSource;

  constructor() {
    const cesiumStore = cesiumState(),
      simulStore = useSimulationStore(),
      customViewer: CustomViewer | null = cesiumStore.getCustomViewer;
    this.entityRoutes = {};
    this.datasource = new CustomDataSource("all_path");
    this.datasource.show = simulStore.isShowPath;
    customViewer?.viewer.dataSources.add(this.datasource);
  }

  /**
   * 初始创建路径
   * @param customViewer
   * @param step
   * @param visualAngle 当前视角
   */
  createInitPath(step: ISideStep, visualAngle: string) {
    const entities: IEntities = {},
      /// 初始时间戳
      startStampTime = step.simul_time * 1000,
      startJulianTime = JulianDate.fromDate(moment(startStampTime).toDate()),
      endJulianTime = JulianDate.addMinutes(
        startJulianTime,
        1,
        new JulianDate()
      ),
      timeInterval = new TimeInterval({
        start: startJulianTime,
        stop: endJulianTime,
      }),
      timeIntervalCollection = new TimeIntervalCollection([timeInterval]),
      datasource = this.datasource,
      entityRoutes = this.entityRoutes;

    datasource && datasource.entities.removeAll();

    /// 筛选实体信息
    step.obj_list && step.obj_list.forEach((model) => {
      this.addEntityInfo(entities, model, startJulianTime);
    });

    // 根据实体创建动画
    for (const key in entities) {
      if (Object.prototype.hasOwnProperty.call(entities, key)) {
        const entityInfo = entities[key],
          entity = this.createEntity(
            entityInfo,
            visualAngle,
            timeIntervalCollection
          );
        entity &&
          entity.id !== undefined &&
          datasource &&
          datasource.entities.add(entity);
        entityInfo.id !== undefined &&
          (entityRoutes[entityInfo.id] = [...entityInfo.routes]);
      }
    }
  }

  /**
   * 创建实体
   * @param entityInfo
   */
  private createEntity(
    entityInfo: RouteEntity,
    visualAngle: string,
    availability?: TimeIntervalCollection
  ) {
    const {
      id,
      name,
      side,
      type,
      //   startStampTime,
      //   stopStampTime,
      positions,
      routes,
    } = entityInfo,
      simulStore = useSimulationStore();
    /// 动画步长为1
    let position: Cartesian3 | SampledPositionProperty =
      entityInfo.positions.data[0];
    /// 动画步长超过1
    if (positions.data.length > 1) {
      position = new SampledPositionProperty();
      /// 位置时间序列
      position.addSamples(positions.time, positions.data);
    }
    if (routes.length > 2) {
      const resourceEntity = new Entity({
        id: id + "",
        // availability,
        position,
        show:
          visualAngle === "all"
            ? true
            : visualAngle === "red" && (simulStore.entityIds.red.indexOf(id + "") !== -1)
              ? true
              : visualAngle === "blue" && (simulStore.entityIds.blue.indexOf(id + "") !== -1) ? true : false,
        polyline: {
          show: !(type?.m_kind === 1 && type?.m_domain === 5),
          positions: new CallbackProperty(() => {
            return Cartesian3.fromDegreesArray(routes);
          }, false),
          width: 1,
          material: new PolylineDashMaterialProperty({
            color:
              side === 1
                ? Color.RED.withAlpha(1)
                : Color.fromCssColorString("rgba(53, 181, 255, 1)"),
          }),
        },
      });
      return resourceEntity;
    }
    return null;
  }

  /**
   * 添加实体信息
   * @param entities
   * @param model
   * @param currentTime
   * @returns
   */
  private addEntityInfo(
    entities: IEntities,
    model: IStepEntityInfo | ITrackEntityInfo,
    currentTime: JulianDate
    // startStampTime: number,
    // stopStampTime?: number
  ) {
    const { m_id, m_EntityName, m_Position, m_Side, m_Heading, m_EntityType } =
      model,
      cartesian3 = Cartesian3.fromDegrees(
        m_Position?.longitude || 0,
        m_Position?.latitude || 0
      );
    if (!defined(cartesian3)) return;
    /// 已存在实体信息，则继续添加旋转、位置数据
    if (entities[m_id]) {
      const entity = entities[m_id];
      /// 位置
      entity.positions.time.push(currentTime);
      entity.positions.data.push(cartesian3);
      entity.routes.push(m_Position?.longitude || 0, m_Position?.latitude || 0);
    }
    /// 添加新实体信息
    else {
      const positions: { time: JulianDate[]; data: Cartesian3[] } = {
        time: [],
        data: [],
      },
        routes: number[] = [];
      /// 位置
      positions.time.push(currentTime);
      positions.data.push(cartesian3);
      routes.push(m_Position?.longitude || 0, m_Position?.latitude || 0);
      entities[m_id] = {
        id: m_id,
        name: m_EntityName,
        side: m_Side,
        type: m_EntityType,
        // startStampTime,
        // stopStampTime,
        positions,
        routes,
      };
    }
  }

  /**
   * 更新路径
   * @param customViewer
   * @param step
   * @param visualAngle 当前视角
   */
  updatePath(step: ISideStep, visualAngle: string) {
    const entities: IEntities = {},
      /// 初始时间戳
      startStampTime = step.simul_time * 1000,
      startJulianTime = JulianDate.fromDate(moment(startStampTime).toDate()),
      endJulianTime = JulianDate.addMinutes(
        startJulianTime,
        1,
        new JulianDate()
      ),
      timeInterval = new TimeInterval({
        start: startJulianTime,
        stop: endJulianTime,
      }),
      timeIntervalCollection = new TimeIntervalCollection([timeInterval]),
      datasource = this.datasource,
      entityRoutes = this.entityRoutes,
      simulStore = useSimulationStore();

    datasource && datasource.entities.removeAll();

    // 筛选实体信息
    step.obj_list && step.obj_list.forEach((model) => {
      this.addEntityInfo(entities, model, startJulianTime);
    });

    // 探测到的实体
    // step.detect_list?.forEach((model) => {
    //   model.m_Side =
    //     visualAngle === "red"
    //       ? SideEnum.blue
    //       : visualAngle === "blue"
    //       ? SideEnum.red
    //       : model.m_Side;
    //   this.addEntityInfo(entities, model, startJulianTime);
    // });

    const newRoutes = {};

    // 根据实体创建动画
    for (const key in entities) {
      if (Object.prototype.hasOwnProperty.call(entities, key)) {
        const entityInfo = entities[key],
          entity = datasource?.entities.getById(key + "");

        if (Object.prototype.hasOwnProperty.call(entityRoutes, key)) {
          entityRoutes[entityInfo.id].push(...entityInfo.routes);
          entityInfo.routes = [...entityRoutes[entityInfo.id]];
        }

        if (entity) {
          // entity.availability.addInterval(timeIntervalCollection);
          entity.polyline &&
            (entity.polyline.positions = new CallbackProperty(() => {
              return Cartesian3.fromDegreesArray(entityInfo.routes);
            }, false));
          entity.show = visualAngle === "all"
            ? true
            : visualAngle === "red" && (simulStore.entityIds.red.indexOf(key + "") !== -1)
              ? true
              : visualAngle === "blue" && (simulStore.entityIds.blue.indexOf(key + "") !== -1) ? true : false
        } else {
          let newEntity = this.createEntity(
            entityInfo,
            visualAngle,
            timeIntervalCollection
          );
          newEntity && datasource?.entities.add(newEntity);
        }

        entityInfo.id !== undefined &&
          (newRoutes[entityInfo.id] = [...entityInfo.routes]);
      }
    }

    this.entityRoutes = { ...newRoutes };
    return true;
  }

  /**
   * 清空历史轨迹数据
   */
  removePath() {
    this.entityRoutes = Object.assign({}, {});
    this.datasource?.entities.removeAll();
  }

  /**
   * 移除路径
   */
  deletePath(customViewer: CustomViewer) {
    this.entityRoutes = {};
    this.datasource?.entities.removeAll();
    this.datasource &&
      customViewer.viewer.dataSources.remove(this.datasource, true);
  }

  /**
   * 切换视角
   */
  updateVisual(visualAngle: string, entityList: string[]) {
    this.datasource.entities.values.forEach((entity) => {
      entity.show = visualAngle === "all" ? true : entityList.includes(entity.id);
    });
  }
}

export function createRoutesManager() {
  return new RoutesManager();
}
